package com.zzt.appframe8.widget;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.TypedArray;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.accessibility.AccessibilityEvent;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.content.res.AppCompatResources;
import androidx.appcompat.widget.TintTypedArray;
import androidx.core.content.ContextCompat;
import androidx.core.graphics.drawable.DrawableCompat;

import com.google.android.material.internal.CheckableImageButton;
import com.google.android.material.internal.ThemeEnforcement;
import com.google.android.material.resources.MaterialResources;
import com.zzt.appframe8.R;

import java.util.ArrayList;
import java.util.Arrays;

/**
 * @author: zeting
 * @date: 2022/9/1
 * {@link com.google.android.material.textfield.TextInputLayout}
 * <p>
 * 使用方法
 * <p>
 * >> password
 * app:mPasswordToggleDrawable="@drawable/login_password_show_or_hide"
 * app:mPasswordToggleEnabled="true"
 * <selector xmlns:android="http://schemas.android.com/apk/res/android">
 * <item android:drawable="@mipmap/icon_password_eye_hide" android:state_checked="false" />
 * <item android:drawable="@mipmap/icon_password_eye_show" android:state_checked="true" />
 * </selector>
 * <p>
 * >> textBackground
 * app:mTextColorBgSelect="@color/m_iet_color_selector"
 * <selector xmlns:android="http://schemas.android.com/apk/res/android"
 * <item android:color="@color/color_d90cfd" android:state_enabled="false" />
 * <item android:color="@color/color_FF445A" android:state_focused="false" android:state_pressed="false" />
 * <item android:color="@color/color_f1b017" />
 * </selector>
 */
@SuppressLint("RestrictedApi")
public class MTextInputLayout extends LinearLayout {
    private static final String TAG = MTextInputLayout.class.getSimpleName();
    EditText editText;
    private final LinearLayout inputLayout; // 输入视图
    private final LinearLayout endIconFrame; // 右边存放按钮视图
    private final CheckableImageButton passwordToggleIconView; // 密码眼睛
    private PasswordToggleEndIconDelegate passwordToggleDelegate; // 密码操作工具
    private final CheckableImageButton clearIconView;// 清除按钮
    private ClearEndIconDelegate clearEndIconDelegate;   // 清除按钮
    private Drawable editTextBackground;// 输入框背景
    // 错误工具
    private final ErrorIndicatorController errorIndicatorController = new ErrorIndicatorController(this);
    private float mEndDrawableWidth;// 右边按钮宽度
    private boolean passwordToggleEnabled;   // 眼睛
    private Drawable passwordToggleDrawable;
    private boolean clearEnabled;   // 删除
    private Drawable clearDrawable;
    private ColorStateList textBgTintList;    // 背景色
    private ColorStateList errorTextTintList;    // 错误颜色
    private float errorTextSize;    // 字体大小

    final OnFocusChangeListener editTextFocusLis = new OnFocusChangeListener() {
        @Override
        public void onFocusChange(View v, boolean hasFocus) {
            Log.d(TAG, "-->  editTextFocusLis onFocusChange hasFocus:" + hasFocus);
            if (inputLayout != null) {
                inputLayout.setPressed(hasFocus);
                inputLayout.setFocusable(hasFocus);
                refreshTextBgDrawableState();
            }
            if (clearEndIconDelegate != null) {
                clearEndIconDelegate.onFocusChange(v, hasFocus);
            }
        }
    };

    public MTextInputLayout(Context context) {
        this(context, null);
    }

    public MTextInputLayout(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, R.attr.textInputStyle);
    }

    public MTextInputLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        setOrientation(VERTICAL);
        setWillNotDraw(false);
        setAddStatesFromChildren(true);

        // 输入
        inputLayout = new LinearLayout(context);
        inputLayout.setOrientation(HORIZONTAL);
        inputLayout.setAddStatesFromChildren(true);
        addView(inputLayout);

        // 最右边按钮
        endIconFrame = new LinearLayout(context);
        endIconFrame.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT));

        // 清除按钮
        clearIconView = new CheckableImageButton(getContext());
        LayoutParams lpc = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        lpc.gravity = Gravity.CENTER;
        clearIconView.setLayoutParams(lpc);
        clearIconView.setBackgroundColor(ContextCompat.getColor(getContext(), android.R.color.transparent));
//        clearIconView = (CheckableImageButton) LayoutInflater.from(getContext()).inflate(R.layout.m_text_input_end_icon, endIconFrame, false);
        clearIconView.setVisibility(VISIBLE);
        endIconFrame.addView(clearIconView);

        // 密码眼睛按钮
        passwordToggleIconView = new CheckableImageButton(getContext());
        LayoutParams lpp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        lpp.gravity = Gravity.CENTER;
        passwordToggleIconView.setLayoutParams(lpp);
        passwordToggleIconView.setBackgroundColor(ContextCompat.getColor(getContext(), android.R.color.transparent));
//        passwordToggleIconView = (CheckableImageButton) LayoutInflater.from(getContext()).inflate(R.layout.m_text_input_end_icon, endIconFrame, false);
        endIconFrame.addView(passwordToggleIconView);
        passwordToggleIconView.setVisibility(VISIBLE);


        int[] ints = {android.R.attr.editTextBackground};
        TypedArray typedArrayBg = context.obtainStyledAttributes(ints);
        editTextBackground = typedArrayBg.getDrawable(0);
        typedArrayBg.recycle();

        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.MTextInputLayout, defStyleAttr, 0);
        // 眼睛
        passwordToggleEnabled = typedArray.getBoolean(R.styleable.MTextInputLayout_mPasswordToggleEnabled, true);
        if (typedArray.hasValue(R.styleable.MTextInputLayout_mPasswordToggleDrawable)) {
            passwordToggleDrawable = typedArray.getDrawable(R.styleable.MTextInputLayout_mPasswordToggleDrawable);
        }
        // 删除
        clearEnabled = typedArray.getBoolean(R.styleable.MTextInputLayout_mClearEnabled, true);
        if (typedArray.hasValue(R.styleable.MTextInputLayout_mClearDrawable)) {
            clearDrawable = typedArray.getDrawable(R.styleable.MTextInputLayout_mClearDrawable);
        }
        // 背景色
        if (typedArray.hasValue(R.styleable.MTextInputLayout_mTextColorBgSelect)) {
            textBgTintList = typedArray.getColorStateList(R.styleable.MTextInputLayout_mTextColorBgSelect);
        } else {
            if (textBgTintList == null) {
                // 如果没有设置，默认系统的
                final TypedArray sysA = context.obtainStyledAttributes(attrs, R.styleable.View, defStyleAttr, 0);
                textBgTintList = sysA.getColorStateList(R.styleable.ViewBackgroundHelper_backgroundTint);
                sysA.recycle();
            }
        }
        // 错误颜色
        errorTextTintList = typedArray.getColorStateList(R.styleable.MTextInputLayout_mErrorTextColor);
        // 错误字体大小
        errorTextSize = typedArray.getDimension(R.styleable.MTextInputLayout_mErrorTextSize, 0);
        // 右边按钮宽度
        mEndDrawableWidth = typedArray.getDimension(R.styleable.MTextInputLayout_mEndDrawableWidth, 0);

        typedArray.recycle();

        if (mEndDrawableWidth > 0) {
            LinearLayout.LayoutParams clearLP = (LayoutParams) clearIconView.getLayoutParams();
            clearLP.width = (int) mEndDrawableWidth;
            LinearLayout.LayoutParams pwdLP = (LayoutParams) passwordToggleIconView.getLayoutParams();
            pwdLP.width = (int) mEndDrawableWidth;
        }
    }

    @Override
    public void setEnabled(boolean enabled) {
        EditText editText = getEditText();
        if (editText != null) {
            editText.setEnabled(enabled);
            if (!enabled) {
                if (inputLayout != null) {
                    inputLayout.setFocusable(false);
                    inputLayout.setPressed(false);
                }
            }
        }
        super.setEnabled(enabled);
        refreshTextBgDrawableState();
    }


    /**
     * 根据状态设置按钮颜色
     */
    public void refreshTextBgDrawableState() {
        if (inputLayout == null) {
            return;
        }

        Drawable background = inputLayout.getBackground();
        DrawableCompat.clearColorFilter(background);
        inputLayout.refreshDrawableState();

        Drawable icon = inputLayout.getBackground();
        if (icon == null || textBgTintList == null || !textBgTintList.isStateful()) {
            return;
        }
        logViewState(editText, "editText");
        logViewState(inputLayout, "inputLayout");

        int color = textBgTintList.getColorForState(editText.getDrawableState(), textBgTintList.getDefaultColor());
        icon = DrawableCompat.wrap(icon).mutate();
        DrawableCompat.setTintList(icon, ColorStateList.valueOf(color));
        inputLayout.setBackground(icon);
    }

    /**
     * 显示当前状态日志
     *
     * @param view
     * @param tagStr
     */
    public void logViewState(View view, String tagStr) {
        boolean enabled = view.isEnabled();
        boolean focused = view.isFocused();
        boolean pressed = view.isPressed();
        Log.i(TAG, "获取当前背景状态 " + tagStr + " \n enabled：" + enabled
                + "\n focused：" + focused
                + "\n pressed：" + pressed
        );
    }


    /**
     * 设置按钮状态
     */
    public int[] mergeIconState(EditText editText) {


        int[] iconStates = editText.getDrawableState();

        int[] inputLayoutStates = inputLayout.getDrawableState();
        int indexI = inputLayoutStates.length;
        int[] statesI = Arrays.copyOf(inputLayoutStates, inputLayoutStates.length + iconStates.length);
        System.arraycopy(iconStates, 0, statesI, indexI, iconStates.length);

        return statesI;
    }

    @Override
    public void addView(@NonNull View child, int index, @NonNull final ViewGroup.LayoutParams params) {
        if (child instanceof EditText) {
            LinearLayout.LayoutParams flp = new LinearLayout.LayoutParams(0, params.height, 1.0f);
            flp.gravity = Gravity.CENTER_VERTICAL | (flp.gravity & ~Gravity.VERTICAL_GRAVITY_MASK);
            inputLayout.addView(child, flp);
            inputLayout.setLayoutParams(params);
            setEditText((EditText) child);
        } else if (child instanceof InputFrameLayout || child instanceof InputLinearLayout || child instanceof InputRelativeLayout) {
            EditText childEditText = loopEdittextView((ViewGroup) child);
            if (childEditText != null) {
                LinearLayout.LayoutParams flp = new LinearLayout.LayoutParams(0, LayoutParams.MATCH_PARENT, 1.0f);
                flp.gravity = Gravity.CENTER_VERTICAL | (flp.gravity & ~Gravity.VERTICAL_GRAVITY_MASK);
                inputLayout.addView(child, flp);
                setEditText(childEditText);
            } else {
                super.addView(child, index, params);
            }
        } else {
            // Carry on adding the View...
            super.addView(child, index, params);
        }
    }

    /**
     * 递归找出当前视图下的 Edittext
     */
    private EditText loopEdittextView(ViewGroup viewGroup) {
        int childCount = viewGroup.getChildCount();
        //  定义子布局输入框
        EditText childEditText = null;
        if (childCount > 0) {
            for (int i = 0; i < childCount; i++) {
                View childAt = viewGroup.getChildAt(i);
                if (childAt instanceof EditText) {
                    childEditText = (EditText) childAt;
                } else if (childAt instanceof ViewGroup) {
                    childEditText = loopEdittextView((ViewGroup) childAt);
                }
            }
        }
        return childEditText;
    }


    /**
     * 设置输入框
     *
     * @param editText
     */
    private void setEditText(EditText editText) {
        this.editText = editText;

        editText.setOnFocusChangeListener(editTextFocusLis);

        LinearLayout.LayoutParams endParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.MATCH_PARENT, 0f);
        inputLayout.addView(endIconFrame, endParams);

        // 设置是否显示密码
        setEnablePassword(passwordToggleEnabled);

        // 设置不显示删除按钮
        setEnableClear(clearEnabled);

        // 设置输入背景，如果没有背景就从edittext中取默认的
        setInputLayoutBackground();
    }


    /**
     * 设置密码眼睛按钮
     */
    public PasswordToggleEndIconDelegate setEnablePassword(boolean passwordToggleEnabled) {
        if (passwordToggleDelegate == null) {
            passwordToggleDelegate = new PasswordToggleEndIconDelegate(this);
        }
        passwordToggleDelegate.setImageBtnEnable(passwordToggleEnabled, passwordToggleIconView);
        if (passwordToggleDrawable != null) {
            passwordToggleIconView.setImageDrawable(passwordToggleDrawable);
        }
        passwordToggleDelegate.initialize();
        return passwordToggleDelegate;
    }

    /**
     * 设置清空输入
     */
    public ClearEndIconDelegate setEnableClear(boolean clearEnabled) {
        if (clearEndIconDelegate == null) {
            clearEndIconDelegate = new ClearEndIconDelegate(this);
        }
        clearEndIconDelegate.setImageBtnEnable(clearEnabled, clearIconView);
        if (clearDrawable != null) {
            clearIconView.setImageDrawable(clearDrawable);
        }
        clearEndIconDelegate.initialize();
        return clearEndIconDelegate;
    }

    /**
     * 获取删除按钮对象
     *
     * @return
     */
    public ClearEndIconDelegate getClearEndIconDelegate() {
        return clearEndIconDelegate;
    }


    /**
     * 给输入框设置背景
     */
    private void setInputLayoutBackground() {
        EditText editText = getEditText();
        if (editText == null) {
            return;
        }
        if (inputLayout != null) {
            // 输入视图设置背景
            if (editTextBackground == null) {
                // 临时背景
                editTextBackground = editText.getBackground();
            }
            inputLayout.setBackground(editTextBackground);
            if (textBgTintList == null) {
                textBgTintList = editText.getBackgroundTintList();
            }
//            if (textBgTintList == null) {
//                textBgTintList = AppCompatResources.getColorStateList(getContext(), R.color.m_text_btn_text_color_selector);
//            }
            inputLayout.setBackgroundTintList(textBgTintList);

            // 删除输入框背景
//            editText.setBackground(null);
//            editText.setBackgroundTintList(AppCompatResources.getColorStateList(getContext(), android.R.color.transparent));
//            setEditTextBackTransparent();
        }
    }

    /**
     * 设置背景为透明色
     */
    public void setEditTextBackTransparent() {
        EditText editText = getEditText();
        if (editText == null) {
            return;
        }
        Drawable icon = editText.getBackground();
        if (icon != null) {
            icon = DrawableCompat.wrap(icon).mutate();
            DrawableCompat.setTintList(icon, AppCompatResources.getColorStateList(getContext(), android.R.color.transparent));
        }
        if (editText.getBackground() != icon) {
            editText.setBackground(icon);
        }
    }


    @Nullable
    public EditText getEditText() {
        return editText;
    }


    @NonNull
    public LinearLayout getInputLayout() {
        return inputLayout;
    }

    public void setErrorIconTintList(@Nullable ColorStateList errorIconTintList) {
        this.errorTextTintList = errorIconTintList;
        Drawable icon = clearIconView.getDrawable();
        if (icon != null) {
            icon = DrawableCompat.wrap(icon).mutate();
            DrawableCompat.setTintList(icon, errorIconTintList);
        }

        if (clearIconView.getDrawable() != icon) {
            clearIconView.setImageDrawable(icon);
        }
    }

    /**
     * 设置错误信息
     */
    public void setError(@Nullable final CharSequence errorText) {
        if (errorIndicatorController == null) {
            return;
        }
        if (errorTextTintList != null) {
            errorIndicatorController.setErrorTextTintList(errorTextTintList);
            errorIndicatorController.setErrorTextSize(errorTextSize);
        }
        if (!errorIndicatorController.isErrorEnabled()) {
            if (TextUtils.isEmpty(errorText)) {
                return;
            }
            errorIndicatorController.setErrorEnabled(true);
        }
        if (!TextUtils.isEmpty(errorText)) {
            errorIndicatorController.showError(errorText);
        } else {
            errorIndicatorController.hideError();
        }
    }


    /**
     * 用来解析是否内部包含了复杂布局
     */
    public static class InputFrameLayout extends FrameLayout {

        public InputFrameLayout(@NonNull Context context) {
            super(context);
        }

        public InputFrameLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
            super(context, attrs);
        }

        public InputFrameLayout(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
        }
    }

    /**
     * 用来解析是否内部包含了复杂布局
     */
    public static class InputLinearLayout extends LinearLayout {

        public InputLinearLayout(Context context) {
            super(context);
        }

        public InputLinearLayout(Context context, @Nullable AttributeSet attrs) {
            super(context, attrs);
        }

        public InputLinearLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
        }
    }

    /**
     * 用来解析是否内部包含了复杂布局
     */
    public static class InputRelativeLayout extends RelativeLayout {

        public InputRelativeLayout(Context context) {
            super(context);
        }

        public InputRelativeLayout(Context context, AttributeSet attrs) {
            super(context, attrs);
        }

        public InputRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
        }
    }
}
